home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 November / Macworld (1999-11).dmg / Updaters / WhiteCap 3.0.4 / WhiteCap Source.sit / WhiteCap Source / Common / Graphics / DrawXX.cpp next >
Text File  |  1999-08-01  |  14KB  |  571 lines

  1. #if P_SZ == 1
  2.     #define PIXTYPE unsigned char
  3.     #define REDSHIFT 4
  4.     #define GRNSHIFT 2
  5.     #define COLMASK 0x3
  6.     #define _Line            Line8
  7.     #define _BoxBlur        BoxBlur8
  8.     #define _CrossBlur        CrossBlur8
  9.     #define _EraseRect        EraseRect8
  10.     #define __Clr(r,g,b)    0
  11. #elif P_SZ == 2
  12.     #define PIXTYPE unsigned short
  13.     #define REDSHIFT 10
  14.     #define GRNSHIFT 5
  15.     #define COLMASK 0x1F
  16.     #define _Line            Line16
  17.     #define _BoxBlur        BoxBlur16
  18.     #define _CrossBlur        CrossBlur16
  19.     #define _EraseRect        EraseRect16
  20.     #define __Clr(r,g,b)    (((r & 0xF800) >> 1) | ((g & 0xF800) >> 6) | (b >> 11))
  21. #elif P_SZ == 4
  22.     #define PIXTYPE unsigned long
  23.     #define REDSHIFT 16
  24.     #define GRNSHIFT 8
  25.     #define COLMASK 0xFF
  26.     #define _Line            Line32
  27.     #define _BoxBlur        BoxBlur32
  28.     #define _CrossBlur        CrossBlur32
  29.     #define _EraseRect        EraseRect32
  30.     #if EG_MAC 
  31.     #define    __Clr(r,g,b)    (((r & 0xFF00) << 8) | (g & 0xFF00) | (b >> 8))
  32.     #elif EG_WIN
  33.     #define    __Clr(r,g,b)    __winRGB( r, g, b )
  34.     #endif
  35.  
  36. #endif
  37.  
  38.  
  39.  
  40.  
  41. #define __doXerr        error_term += dy;                \
  42.                         if ( error_term >= dx ) {        \
  43.                             error_term -= dx;            \
  44.                             basePtr += rowOffset;        \
  45.                             ymov--;                        \
  46.                         }
  47.                         
  48.                         
  49. #define __doYerr        error_term += dx;                \
  50.                         if ( error_term >= dy ) {        \
  51.                             error_term -= dy;            \
  52.                             basePtr += xDirection;        \
  53.                             xmov--;                        \
  54.                         }
  55.  
  56. #define __calcClr        color = __Clr( R, G, B );        \
  57.                         R += dR;                        \
  58.                         G += dG;                        \
  59.                         B += dB;
  60.  
  61.  
  62. #define __circ( dia, a )    switch ( (dia) )        {                                    \
  63.                                 case 2:        a = "\0\0"; break;                            \
  64.                                 case 3:        a = "\0\0\0"; break;                        \
  65.                                 case 4:        a = "\1\0\0\1"; break;                        \
  66.                                 case 5:        a = "\1\0\0\0\1"; break;                    \
  67.                                 case 6:        a = "\1\0\0\0\0\1"; break;                    \
  68.                                 case 7:        a = "\2\1\0\0\0\1\2"; break;                \
  69.                                 case 8:        a = "\2\1\0\0\0\0\1\2"; break;                \
  70.                                 case 9:        a = "\3\1\1\0\0\0\1\1\3"; break;            \
  71.                                 case 10:    a = "\3\1\1\0\0\0\0\1\1\3"; break;            \
  72.                                 case 11:    a = "\4\2\1\1\0\0\0\1\1\2\4"; break;        \
  73.                                 case 12:    a = "\4\2\1\1\0\0\0\0\1\1\2\4"; break;        \
  74.                             }
  75.                                 
  76.  
  77. #define CLR_INTERP 1
  78. #include "LineXX.cpp"
  79. #undef CLR_INTERP
  80. #include "LineXX.cpp"
  81.  
  82. /*
  83. void PixPort::_Line( int sx, int sy, int ex, int ey, long inColor ) {
  84.     int xDirection, rowOffset, error_term;
  85.     char* basePtr;
  86.     int xmov, ymov, dx, dy, t;
  87.     
  88.     // Clipping: Set the pen loc to a point that's in and stop drawing once/if the pen moves out
  89.     if ( sx < 0 || sx > mX || sy < 0 || sy > mY ) {
  90.         t = ex; ex = sx; sx = t;
  91.         t = ey; ey = sy; sy = t;
  92.     }
  93.     
  94.     // Exit if the start pt is out of bounds (wimpy clipping, eh?)
  95.     if ( sx < 0 || sx > mX || sy < 0 || sy > mY )
  96.         return;
  97.  
  98.     // In Win32, everything's upside down
  99.     #if EG_WIN
  100.     sy = mY - sy;
  101.     ey = mY - ey;
  102.     #endif    
  103.     
  104.     dx = ex - sx;
  105.     dy = ey - sy;
  106.         
  107.     // moving left or right?
  108.     xmov = dx;
  109.     if ( dx < 0 ) {
  110.         xmov = -dx;
  111.         if ( sx - xmov < 0 )
  112.             xmov = sx;
  113.         xDirection = - P_SZ;
  114.         dx = -dx; }
  115.     else if ( dx > 0 ) {
  116.         if ( sx + xmov > mX )
  117.             xmov = mX - sx;
  118.         xDirection = P_SZ;  }
  119.     else 
  120.         xDirection = 0;
  121.  
  122.     // moving up or down?
  123.     ymov = dy;
  124.     if ( dy < 0 ) {
  125.         ymov = -dy;
  126.         if ( sy - ymov < 0 )
  127.             ymov = sy;
  128.         rowOffset = - mBytesPerRow;
  129.         dy = -dy; }
  130.     else if ( dy > 0 ) {
  131.         if ( sy + ymov > mY )
  132.             ymov = mY - sy;
  133.         rowOffset = mBytesPerRow;  } 
  134.     else
  135.         rowOffset = 0;
  136.  
  137.     basePtr = mBits + sy * mBytesPerRow + sx * P_SZ;
  138.     error_term = 0;
  139.  
  140.     // Draw the line
  141.     if ( dx >= dy ) {
  142.         
  143.         // Start counting off in x
  144.         for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
  145.         
  146.             *((PIXTYPE*) basePtr) = inColor;
  147.             basePtr += xDirection;
  148.  
  149.             // Check to see if we need to move the pixelOffset in the y direction.
  150.             error_term += dy;
  151.             if ( error_term >= dx ) {
  152.                 error_term -= dx;
  153.                 basePtr += rowOffset;
  154.                 ymov--;
  155.             }
  156.         } }
  157.     else {
  158.         // Start counting off in y
  159.         for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
  160.         
  161.             *((PIXTYPE*) basePtr) = inColor;
  162.             basePtr += rowOffset;
  163.  
  164.             // Check to see if we need to move the pixelOffset in the y direction.
  165.             error_term += dx;
  166.             if ( error_term >= dy ) {
  167.                 error_term -= dy;
  168.                 basePtr += xDirection;
  169.                 xmov--;
  170.             }
  171.         }
  172.     }
  173. }
  174.  
  175. */
  176.  
  177.  
  178.  
  179. /*
  180. void PixPort::_LineW( int sx, int sy, int ex, int ey, int inWidth, long inColor ) {
  181.     int xDirection, rowOffset, error_term;
  182.     char* basePtr, *rowPtr;
  183.     int xmov, ymov, dx, dy, t, i, xDir, yDir;
  184.     
  185.     // Clipping: Set the pen loc to a point that's in and stop drawing once/if the pen moves out
  186.     if ( sx < 0 || sx > mX || sy < 0 || sy > mY ) {
  187.         t = ex; ex = sx; sx = t;
  188.         t = ey; ey = sy; sy = t;
  189.     }
  190.     
  191.     // Exit if the start pt is out of bounds (wimpy clipping, eh?)
  192.     if ( sx < 0 || sx > mX || sy < 0 || sy > mY )
  193.         return;
  194.  
  195.     // In Win32, everything's upside down
  196.     #if EG_WIN
  197.     sy = mY - sy;
  198.     ey = mY - ey;
  199.     #endif    
  200.     
  201.     dx = ex - sx;
  202.     dy = ey - sy;
  203.         
  204.     // moving left or right?
  205.     xmov = dx;
  206.     if ( dx < 0 ) {
  207.         xmov = -dx;
  208.         if ( sx - xmov < 0 )
  209.             xmov = sx;
  210.         xDirection = - P_SZ;
  211.         xDir = -1;
  212.         dx = -dx; }
  213.     else if ( dx > 0 ) {
  214.         if ( sx + xmov > mX )
  215.             xmov = mX - sx;
  216.         xDir = 1;
  217.         xDirection = P_SZ;  }
  218.     else {
  219.         xDirection = 0;
  220.         xDir = 0;
  221.     }
  222.  
  223.     // moving up or down?
  224.     ymov = dy;
  225.     if ( dy < 0 ) {
  226.         ymov = -dy;
  227.         if ( sy - ymov < 0 )
  228.             ymov = sy;
  229.         yDir = 1;
  230.         rowOffset = - mBytesPerRow;
  231.         dy = -dy; }
  232.     else if ( dy > 0 ) {
  233.         if ( sy + ymov > mY )
  234.             ymov = mY - sy;
  235.         yDir = -1;
  236.         rowOffset = mBytesPerRow;  } 
  237.     else {
  238.         yDir = 0;
  239.         rowOffset = 0;
  240.     }
  241.  
  242.     
  243.     basePtr = mBits + sy * mBytesPerRow + sx * P_SZ;
  244.     error_term = 0;
  245.  
  246.     // Draw the line
  247.     if ( dx >= dy ) {
  248.         bool didRow = false;
  249.         int limx;
  250.         if ( xDirection > 0 )
  251.             limx = ex;
  252.         else 
  253.             limx = sx;
  254.         if ( limx > mX )
  255.             limx = mX;
  256.         
  257.  
  258.         // Start counting off in x
  259.         for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
  260.     
  261.             if ( ! didRow ) {
  262.                 for ( i = 0; i < inWidth && sx + i <= limx; i++ ) {
  263.                     ((PIXTYPE*) basePtr)[i] = inColor;
  264.                 }
  265.                 didRow = true;
  266.             }
  267.             sx += xDir;
  268.     
  269.             basePtr += xDirection;
  270.  
  271.             // Check to see if we need to move the pixelOffset in the y direction.
  272.             error_term += dy;
  273.             if ( error_term >= dx ) {
  274.                 error_term -= dx;
  275.                 
  276.                 // Finish the rest of the line width, making sure we don't go off the right
  277.                 didRow = false;
  278.                 basePtr += rowOffset;
  279.                 ymov--;
  280.             }
  281.         } }
  282.     else {        
  283.         
  284.         // Start counting off in y
  285.         for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
  286.         
  287.             // Do the whole line width, making sure we don't go off the right
  288.             for ( i = 0; i < inWidth && sx + i < mX; i++ )
  289.                 ((PIXTYPE*) basePtr)[i] = inColor;
  290.             basePtr += rowOffset;
  291.  
  292.             // Check to see if we need to move the pixelOffset in the y direction.
  293.             error_term += dx;
  294.             if ( error_term >= dy ) {
  295.                 error_term -= dy;
  296.                 basePtr += xDirection;
  297.                 xmov--;
  298.                 sx += xDir;
  299.             }
  300.         }
  301.     }
  302. }*/
  303.  
  304.  
  305.  
  306. void PixPort::_EraseRect( const Rect* inRect ) {
  307.     long width, height;
  308.     int x, y;
  309.     char*    base;
  310.     Rect    r;
  311.  
  312.     // Don't let us draw in random parts of memory -- clip inRect
  313.     if ( inRect ) {
  314.         r = *inRect;
  315.         __clipPt( r.left, r.top )
  316.         __clipPt( r.right, r.bottom ) }
  317.     else {
  318.         r.top = r.left = 0;
  319.         r.right = mX;
  320.         r.bottom = mY;
  321.     }
  322.     width     = r.right - r.left;
  323.     height    = r.bottom - r.top;
  324.  
  325.     
  326.     // In Win32, everything's upside down
  327.     #if EG_WIN
  328.     r.top = mY - r.bottom;
  329.     #endif
  330.     
  331.     base = mBits + mBytesPerPix * r.left + r.top * mBytesPerRow;
  332.     for ( y = 0; y <= height; y++ ) {
  333.         for ( x = 0; x <= width; x++ ) {
  334.             *((PIXTYPE*) base) = mBackColor;
  335.             base += P_SZ;
  336.         }
  337.         base += mBytesPerRow - P_SZ * (width + 1);
  338.     }
  339. }
  340.  
  341.  
  342.  
  343. void PixPort::_CrossBlur( char* inSrce, int inWidth, int inHeight, int inBytesPerRow, unsigned char* inRowBuf ) {
  344.     long leftR, leftG, leftB, cenR, cenG, cenB, rightR, rightG, rightB;
  345.     long topR, topG, topB, val, botR, botG, botB, x;
  346.     unsigned char *rowPos;
  347.     
  348.     // Init inRowBuf[]
  349.     rowPos = inRowBuf;
  350.     for ( x = 0; x < inWidth; x++ ) {
  351.         val = ((PIXTYPE*) inSrce)[ x ];
  352.         rowPos[ 0 ]  = val >> REDSHIFT; 
  353.         rowPos[ 1 ] = (val >> GRNSHIFT) & COLMASK;
  354.         rowPos[ 2 ] = val & COLMASK;
  355.         rowPos += 3;
  356.     }
  357.     
  358.     // Go thru row by row in the source img
  359.     for ( ; inHeight > 0; inHeight-- ) {
  360.     
  361.         // Prime the x-loop and get left and cen pixels
  362.         val = *((PIXTYPE*) inSrce );
  363.         leftR = cenR = val >> REDSHIFT; 
  364.         leftG = cenG = (val >> GRNSHIFT) & COLMASK;
  365.         leftB = cenB = val & COLMASK;
  366.         
  367.         rowPos = inRowBuf;
  368.                 
  369.         for ( x = 0; x < inWidth; x++ ) {
  370.         
  371.             // Get top pixel
  372.             topR = rowPos[ 0 ];
  373.             topG = rowPos[ 1 ];
  374.             topB = rowPos[ 2 ];
  375.             
  376.             // Get right-most pixel
  377.             val = ((PIXTYPE*) inSrce)[ x + 1 ];
  378.             rightR = val >> REDSHIFT; 
  379.             rightG = (val >> GRNSHIFT) & COLMASK;
  380.             rightB = val & COLMASK;
  381.  
  382.             // Get bottom pixel
  383.             val = ((PIXTYPE*) (inSrce + inBytesPerRow))[ x ];
  384.             botR = val >> REDSHIFT; 
  385.             botG = (val >> GRNSHIFT) & COLMASK;
  386.             botB = val & COLMASK;
  387.             
  388.             *rowPos = cenR;        rowPos++;
  389.             *rowPos = cenG;        rowPos++;
  390.             *rowPos = cenB;        rowPos++;
  391.             
  392.             botR = ( ( cenR << 2 ) + 3 * ( leftR + rightR + topR + botR ) ) >> 4;
  393.             botG = ( ( cenG << 2 ) + 3 * ( leftG + rightG + topG + botG ) ) >> 4;
  394.             botB = ( ( cenB << 2 ) + 3 * ( leftB + rightB + topB + botB ) ) >> 4;
  395.             ((PIXTYPE*) inSrce )[ x ] = ( botR << REDSHIFT ) | ( botG << GRNSHIFT ) | botB;
  396.             
  397.             // Re-use already-fetched memory
  398.             leftR = cenR;    cenR = rightR;
  399.             leftG = cenG;    cenG = rightG;
  400.             leftB = cenB;    cenB = rightB;
  401.         }
  402.         
  403.         inSrce += inBytesPerRow;
  404.     }
  405. }
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413. #define UL unsigned long
  414. #define DENOM_SHIFT 14
  415.  
  416.  
  417. void PixPort::_BoxBlur( char* inSrce, char* inDest, int inBoxWidth, int inWidth, int inHeight, int inSrceRowWidth, int inDestRowWidth, unsigned long* b, unsigned long inBackColor ) {
  418.     register unsigned long* bEnd;
  419.     register char *dest;
  420.     register unsigned long b1R, b1G, b1B, b2R, b2G, b2B, b3R, b3G, b3B, val, box9W, i, numerator;
  421.     register int x, half, useWidth;
  422.     
  423.     i = inBoxWidth * inBoxWidth * inBoxWidth;
  424.     numerator = ( 1 << DENOM_SHIFT ) / ( i );
  425.     box9W = 9 * inBoxWidth;        // 3 colors, 3 boxes
  426.     bEnd = b + box9W;
  427.     
  428.     b1R = 0; b1G = 0; b1B = 0;
  429.     b2R = 0; b2G = 0; b2B = 0;
  430.     b3R = i >> 1; b3G = b3R; b3B = b3R;        // round up when > .5
  431.     for ( i = 0; i < box9W; i++ ) {
  432.         b[ i ] = 0;
  433.     }
  434.     
  435.     half = 3 * inBoxWidth / 2 - 1;
  436.     inSrce += P_SZ * half;
  437.     useWidth = inWidth - half - inBoxWidth % 2;
  438.  
  439.     // Go thru row by row in the source img
  440.     for ( ; inHeight > 0; inHeight-- ) {
  441.         
  442.         // Go thru the row
  443.         dest = inDest;
  444.         
  445.         for ( x = - half - 5; x < inWidth; x++ ) {
  446.                 
  447.             // Maintain the circular buffer
  448.             if ( b == bEnd )
  449.                 b -= box9W; 
  450.                 
  451.             // p = fetch next pix from b1
  452.             if ( x >= 0 && x < useWidth ) {
  453.                 val = *( (PIXTYPE*) inSrce );
  454.                 inSrce += P_SZ; }
  455.             else
  456.                 val = inBackColor;
  457.             
  458.             // p' += new pix - end pix and store new pix
  459.             i = val >> REDSHIFT;                  b1R += i - b[0];        b[0] = i;
  460.             i = (val >> GRNSHIFT) & COLMASK;     b1G += i - b[1];        b[1] = i;
  461.             i = val & COLMASK;                  b1B += i - b[2];        b[2] = i;
  462.  
  463.             // Store the b2's new pix and calc its new pixel
  464.             b2R += b1R - b[3];        b[3] = b1R;
  465.             b2G += b1G - b[4];        b[4] = b1G;
  466.             b2B += b1B - b[5];        b[5] = b1B;
  467.  
  468.             // Store the b3's new pix and calc its new pixel
  469.             b3R += b2R - b[6];        b[6] = b2R;
  470.             b3G += b2G - b[7];        b[7] = b2G;
  471.             b3B += b2B - b[8];        b[8] = b2B;
  472.             
  473.             // Transpose the final pixel calculations
  474.             if ( x >= 0 ) {
  475.                 *((PIXTYPE*)dest) = ( (( numerator * b3R ) >> DENOM_SHIFT) << REDSHIFT ) | ( (( numerator * b3G ) >> DENOM_SHIFT) << GRNSHIFT ) | (( numerator * b3B ) >> DENOM_SHIFT);
  476.                 dest += inDestRowWidth;
  477.             }
  478.             
  479.             // Maintain our circular buffer
  480.             b += 9;
  481.  
  482.         }
  483.             
  484.         // Do next row
  485.         inSrce += inSrceRowWidth - P_SZ * useWidth;
  486.         inDest += P_SZ;
  487.     }
  488. }
  489.  
  490.  
  491.  
  492. /*
  493. this modification to BoxBlur only blurs the x row
  494. void PixPort::_BoxBlur( char* inSrce, char*, int inBoxWidth, int inWidth, int inHeight, int inSrceRowWidth, int, char* b, unsigned long inBackColor ) {
  495.  
  496.     register char *bEnd;
  497.     register unsigned long b1R, b1G, b1B, b2R, b2G, b2B, b3R, b3G, b3B, val, box9W, i, denom;
  498.     register int x, half, useWidth;
  499.     
  500.     
  501.     denom = inBoxWidth * inBoxWidth * inBoxWidth;
  502.     box9W = 36 * inBoxWidth;        // 3 colors, 3 boxes, 4 bytes per long
  503.     bEnd = b + box9W;
  504.     
  505.     b1R = 0; b1G = 0; b1B = 0;
  506.     b2R = 0; b2G = 0; b2B = 0;
  507.     b3R = 0; b3G = 0; b3B = 0;
  508.     for ( i = 0; i < 9 * inBoxWidth; ) {
  509.         *((UL*) b + i) = 0;    i++;
  510.     }
  511.     
  512.     half = 3 * inBoxWidth / 2 - 1;
  513.     inSrce += P_SZ * half;
  514.     useWidth = inWidth - half - inBoxWidth % 2;
  515.  
  516.     // Go thru row by row in the source img
  517.     for ( ; inHeight > 0; inHeight-- ) {
  518.                 
  519.         for ( x = - half - 5; x < inWidth; x++ ) {
  520.                 
  521.             // Maintain our circular buffer
  522.             if ( b == bEnd ) 
  523.                 b -= box9W; 
  524.  
  525.             // p = fetch next pix from b1
  526.             if ( x >= 0 && x < useWidth ) {
  527.                 val = *( (PIXTYPE*) inSrce );}
  528.             else
  529.                 val = inBackColor;
  530.             
  531.             // p' += new pix - end pix and store new pix
  532.             i = val >> REDSHIFT;                  b1R += i - *((UL*)b);        *((UL*)b) = i;    b += 4;
  533.             i = (val >> GRNSHIFT) & COLMASK;     b1G += i - *((UL*)b);        *((UL*)b) = i;    b += 4;
  534.             i = val & COLMASK;                  b1B += i - *((UL*)b);        *((UL*)b) = i;    b += 4;
  535.  
  536.             // Store the b2's new pix and calc its new pixel
  537.             b2R += b1R - *((UL*)b);        *((UL*)b) = b1R;    b += 4;
  538.             b2G += b1G - *((UL*)b);        *((UL*)b) = b1G;    b += 4;
  539.             b2B += b1B - *((UL*)b);        *((UL*)b) = b1B;    b += 4;
  540.  
  541.             // Store the b3's new pix and calc its new pixel
  542.             b3R += b2R - *((UL*)b);        *((UL*)b) = b2R;    b += 4;
  543.             b3G += b2G - *((UL*)b);        *((UL*)b) = b2G;    b += 4;
  544.             b3B += b2B - *((UL*)b);        *((UL*)b) = b2B;    b += 4;
  545.             
  546.             // Transpose the final pixel calculations
  547.             if ( x >= 0 ) {
  548.                 *((PIXTYPE*)inSrce) = ( (b3R/denom) << REDSHIFT ) | ( ( b3G/denom ) << GRNSHIFT ) | ( b3B/denom );
  549.                 inSrce += P_SZ;
  550.             }
  551.         }
  552.             
  553.         // Do next row
  554.         inSrce += inSrceRowWidth - P_SZ * inWidth;
  555.     }
  556. }
  557. */
  558.  
  559.  
  560.  
  561. #undef PIXTYPE
  562. #undef REDSHIFT
  563. #undef GRNSHIFT
  564. #undef COLMASK
  565. #undef _Line
  566. #undef _LineW
  567. #undef _BoxBlur
  568. #undef _CrossBlur
  569. #undef _EraseRect
  570. #undef __Clr
  571.